from train_svm import *
from train_svm_link import *
from train_lr import *
from train_hr import *
from train_br import *
from train_xgboost import *
from train_kmeans import *
from train_rf import *
from train_lsvm import *

def merge(isEval, task, cols, weights=[]):
    func = ['svm', 'svm_link', 'lr', 'xgboost', 'hr', 'br', 'kmeans', 'rf', 'lsvm']
    n = len(cols)
    if weights == []:
        weights = [1.0 / n] * n
    else:
        weights = list(np.array(weights) / sum(weights))
    tot = 0
    num = 5 + (task == 1)
    result = np.zeros((num, 7, 12))

    for i in range(n):
        if cols[i] not in func:
            continue
        tot += 1
        tmp = eval('train_' + cols[i] + '(%s,%d)'%(str(isEval), task))
        assert len(tmp) == num
        for j in range(num):
            assert len(tmp[j]) == 7
            for k in range(7):
                assert len(tmp[j,k]) == 12
                for z in range(12):
                    result[j,k,z] += tmp[j,k,z] * weights[i]

    if task == 2 and not isEval:
        # 0
        multi = 56.0 / (np.sum(result[0,5,0:6]) / 6)
        for i in range(6):
            result[0,5,i] *= multi

        multi = 96.0 / (np.sum(result[0,6,0:6]) / 6)
        for i in range(6):
            result[0,6,i] *= multi

        # 2
        multi = 16.5 / (np.sum(result[2,5,0:6]) / 6)
        for i in range(6):
            result[2,5,i] *= multi

        multi = 14.9 / (np.sum(result[2,5,6:12]) / 6)
        for i in range(6,12):
            result[2,5,i] *= multi

        multi = 45.0 / (np.sum(result[2,6,0:6]) / 6)
        for i in range(6):
            result[2,6,i] *= multi

        multi = 11.1 / (np.sum(result[2,6,6:12]) / 6)
        for i in range(6,12):
            result[2,6,i] *= multi

    if len(result) == 0:
        return

    if not isEval:
        trans = Translate()
        trans.translate(result, path = './result_merger', task = task)
    else:
        if task == 1:
            data0 = np.load('./data_task1/traindata_part0_normalizing.npz')
            data1 = np.load('./data_task1/traindata_part1_normalizing.npz')
            evallabel = np.concatenate((data0['labels'][:,-7:,:], data1['labels'][:,-7:,:]), axis=2)
        if task == 2:
            data0 = np.load('./data_task2/traindata_part0_normalizing.npz')
            data1 = np.load('./data_task2/traindata_part1_normalizing.npz')
            evallabel = np.concatenate((data0['labels'][:,-7:,:], data1['labels'][:,-7:,:]), axis=2)
        evaluate = Evaluate()
        MAPE = evaluate.evaluate_test(result, evallabel)
        if task == 1:
            print 'travel time MAPE: ' + str(MAPE)
            return MAPE
        if task == 2:
            print 'traffic volume MAPE: ' + str(MAPE)
            return MAPE


if __name__ == '__main__':
    
    # merge(True, 1, ['svm_link', 'svm', 'xgboost', 'rf'], [1.0/1, 1.0/2, 1.0/4, 1.0/3])
    merge(True, 1, ['svm_link', 'svm'])  # 0.15953

    # merge(True, 2, ['svm', 'hr'])
    # merge(False, 2, ['lsvm', 'hr', 'rf'])  # 0.1293
    # merge(True, 2, ['lsvm', 'hr', 'svm'])  # 0.1308
